package pl.enigmatic.util;

import java.util.ArrayList;
import java.util.regex.Pattern;


public class Path {

	public final static String SEP = "/";
	public final static String CURRENT = ".";
	public final static String UP = "..";
	private static final Pattern slashes = Pattern.compile("/+");

	public static final String clean(final String path) {
		if (Strings.empty(path)) {
			return SEP;
		} else {
			final ArrayList<String> array = new ArrayList<String>();
			final String start = path.startsWith(SEP) ? SEP : "";
			final String end = path.endsWith(SEP) ? SEP : "";
			for (final String string : slashes.matcher(path).replaceAll(SEP).split(SEP)) {
				if (!CURRENT.equals(string)) {
					array.add(string);
				}
			}
			while (array.contains(UP)) {
				final int index = array.indexOf(UP);
				array.remove(index);
				if (index > 0) {
					array.remove(index - 1);
				}
			}
			return slashes.matcher(start + Strings.concatenate(SEP, array.toArray(new String[array.size()])) + end).replaceAll(SEP);
		}
	}

	public static boolean isAbsolute(final String path) {
		return Strings.empty(path) || path.startsWith(SEP);
	}

	public static String getAbsolutePath(final String current, final String relative) {
		if (isAbsolute(relative)) {
			return clean(relative);
		} else {
			return clean(current + SEP + relative);
		}
	}

	public static String getDeepestDirectory(String path) {
		String dir = null;
		int lastIndex;

		if (path != null && path.trim().length() > 0) {
			path = path.trim();

			if (path.endsWith(SEP) && path.length() > 1) {
				path = path.substring(0, path.length() - 1);
			}

			dir = path;

			if (path.length() > 1) {
				lastIndex = path.lastIndexOf(SEP);

				if (lastIndex >= 0) {
					dir = path.substring(lastIndex + 1);
				}
			}
		}

		return dir;
	}

	public static String getParentDirectory(String path) {
		String parentDir = SEP;
		int lastIndex;

		if (path != null && path.trim().length() > 0) {
			path = path.trim();

			if (path.endsWith(SEP) && path.length() > 1) {
				path = path.substring(0, path.length() - 1);
			}

			if (path.length() > 1) {
				lastIndex = path.lastIndexOf(SEP);

				if (lastIndex > 0) {
					parentDir = path.substring(0, lastIndex);
				}
			}
		}

		return parentDir;
	}

	public static String getFilename(final String path) {
		String split[] = path.split("\\\\");
		split = split[split.length - 1].split("/");
		return split[split.length - 1];
	}

	public static String[] splitDirAndFile(String path) {
		final String[] arr = new String[2];
		int lastIndex;

		if (path != null && path.trim().length() > 0) {
			path = path.trim();

			if (!path.endsWith(SEP)) {
				lastIndex = path.lastIndexOf(SEP);

				if (lastIndex >= 0) {
					arr[0] = path.substring(0, lastIndex);
					arr[1] = path.substring(lastIndex + 1, path.length());
				} else {
					arr[0] = SEP; // Assume Root Directory
					arr[1] = path;
				}
			} else if (path.length() > 1) {
				arr[0] = path.substring(0, path.length() - 1);
			} else {
				arr[0] = path;
			}
		}

		return arr;
	}

	public static String getFileExt(String path) {
		path = getFilename(path);
		final String[] split = path.split("\\.");
		return split[split.length - 1];
	}

	public static String getFilenameNoExt(String filepath) {
		filepath = getFilename(filepath);
		return filepath.substring(0, filepath.lastIndexOf('.'));
	}

	private final String base;

	public Path(final String base) {
		this.base = Strings.empty(base) ? SEP : clean(base);
	}

	public String getBase() {
		return base;
	}

	public String getAbsolutePath(final String relative) {
		return getAbsolutePath(base, relative);
	}
}
